/*
 * Copyright (C) 2024-2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup CryptoSignatureApi
 * @{
 *
 * @brief 为应用提供验签接口。
 *
 * @since 12
 */

/**
 * @file crypto_signature.h
 *
 * @brief 定义验签接口。
 *
 * @library libohcrypto.so
 * @include <CryptoArchitectureKit/crypto_signature.h>
 * @kit CryptoArchitectureKit
 * @syscap SystemCapability.Security.CryptoFramework
 * @since 12
 */

#ifndef CRYPTO_SIGNATURE_H
#define CRYPTO_SIGNATURE_H

#include "crypto_common.h"
#include "crypto_asym_key.h"
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 定义签名验签参数类型。
 *
 * @since 12
 */
typedef enum {
    /** 表示RSA算法中，使用PSS模式时，消息摘要功能的算法名。*/
    CRYPTO_PSS_MD_NAME_STR = 100,
    /** 表示RSA算法中，使用PSS模式时，掩码生成算法（目前仅支持MGF1）。*/
    CRYPTO_PSS_MGF_NAME_STR = 101,
    /** 表示RSA算法中，使用PSS模式时，MGF1掩码生成功能的消息摘要参数。*/
    CRYPTO_PSS_MGF1_NAME_STR = 102,
    /** 表示RSA算法中，使用PSS模式时，盐值的长度，长度以字节为单位。*/
    CRYPTO_PSS_SALT_LEN_INT = 103,
    /** 表示RSA算法中，使用PSS模式时，用于编码操作的整数，值为1。*/
    CRYPTO_PSS_TRAILER_FIELD_INT = 104,
    /** 表示SM2算法中，用户身份标识字段。*/
    CRYPTO_SM2_USER_ID_DATABLOB = 105,
} CryptoSignature_ParamType;

/**
 * @brief 定义验签结构体。
 *
 * @since 12
 */
typedef struct OH_CryptoVerify OH_CryptoVerify;

/**
 * @brief 定义签名结构体。
 *
 * @since 20
 */
typedef struct OH_CryptoSign OH_CryptoSign;

/**
 * @brief 创建验签实例。
 *
 * @param algoName 用于生成验签实例的算法名称。\n
 * 例如"RSA1024|PKCS1|SHA256"
 * @param verify 指向验签实例的指针。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_INVALID_PARAMS：参数无效。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 12
 */
OH_Crypto_ErrCode OH_CryptoVerify_Create(const char *algoName, OH_CryptoVerify **verify);

/**
 * @brief 传入公钥初始化验签实例。
 *
 * @param ctx 指向验签实例。
 * @param pubKey 公钥对象。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_INVALID_PARAMS：参数无效。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @see OH_CryptoVerify_Update
 * @see OH_CryptoVerify_Final
 * @since 12
 */
OH_Crypto_ErrCode OH_CryptoVerify_Init(OH_CryptoVerify *ctx, OH_CryptoPubKey *pubKey);

/**
 * @brief 追加待验签数据。
 *
 * @param ctx 指向验签实例。
 * @param in 传入的消息。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_INVALID_PARAMS：参数无效。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @see OH_CryptoVerify_Init
 * @see OH_CryptoVerify_Final
 * @since 12
 */
OH_Crypto_ErrCode OH_CryptoVerify_Update(OH_CryptoVerify *ctx, Crypto_DataBlob *in);

/**
 * @brief 对数据进行验签。
 *
 * @param ctx 指向验签实例。
 * @param in 传入的数据。
 * @param signData 签名数据。
 * @return 表示验签是否通过。
 * @see OH_CryptoVerify_Init
 * @see OH_CryptoVerify_Update
 * @since 12
 */
bool OH_CryptoVerify_Final(OH_CryptoVerify *ctx, Crypto_DataBlob *in, Crypto_DataBlob *signData);

/**
 * @brief 对签名数据进行恢复操作。
 *
 * @param ctx 指向验签实例。
 * @param signData 签名数据。
 * @param rawSignData 验签恢复的数据。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_INVALID_PARAMS：参数无效。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 12
 */
OH_Crypto_ErrCode OH_CryptoVerify_Recover(OH_CryptoVerify *ctx, Crypto_DataBlob *signData,
    Crypto_DataBlob *rawSignData);

/**
 * @brief 获取验签算法名称。
 *
 * @param ctx 指向验签实例。
 * @return 返回验签算法名称。
 * @since 12
 */
const char *OH_CryptoVerify_GetAlgoName(OH_CryptoVerify *ctx);

/**
 * @brief 设置验签参数。
 *
 * @param ctx 指向验签实例。
 * @param type 用于指定需要设置的验签参数。
 * @param value 用于指定验签参数的具体值。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_INVALID_PARAMS：参数无效。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 12
 */
OH_Crypto_ErrCode OH_CryptoVerify_SetParam(OH_CryptoVerify *ctx, CryptoSignature_ParamType type,
    Crypto_DataBlob *value);

/**
 * @brief 获取验签参数。
 *
 * @param ctx 指向验签实例。
 * @param type 用于指定需要获取的验签参数。
 * @param value 获取的验签参数的具体值。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_INVALID_PARAMS：参数无效。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 12
 */
OH_Crypto_ErrCode OH_CryptoVerify_GetParam(OH_CryptoVerify *ctx, CryptoSignature_ParamType type,
    Crypto_DataBlob *value);

/**
 * @brief 销毁验签实例。
 *
 * @param ctx 指向验签实例。
 * @since 12
 */
void OH_CryptoVerify_Destroy(OH_CryptoVerify *ctx);

/**
 * @brief 根据给定的算法名称创建签名实例。
 *
 * @param algoName 用于生成签名实例的算法名称。\n
 * 例如"RSA|PKCS1|SHA384"、"ECC|SHA384"。
 * @param sign 签名实例。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoSign_Create(const char *algoName, OH_CryptoSign **sign);

/**
 * @brief 初始化签名实例。
 *
 * @param ctx 指向签名实例。
 * @param privKey 私钥。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @see OH_CryptoSign_Update
 * @see OH_CryptoSign_Final
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoSign_Init(OH_CryptoSign *ctx, OH_CryptoPrivKey *privKey);

/**
 * @brief 更新需要签名的数据。
 *
 * @param ctx 指向签名实例。
 * @param in 需要签名的数据。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @see OH_CryptoSign_Init
 * @see OH_CryptoSign_Final
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoSign_Update(OH_CryptoSign *ctx, const Crypto_DataBlob *in);

/**
 * @brief 完成签名操作。
 *
 * @param ctx 指向签名实例。
 * @param in 需要签名的数据。
 * @param out 签名结果。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @see OH_CryptoSign_Init
 * @see OH_CryptoSign_Update
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoSign_Final(OH_CryptoSign *ctx, const Crypto_DataBlob *in, Crypto_DataBlob *out);

/**
 * @brief 获取签名实例的算法名称。
 *
 * @param ctx 指向签名实例。
 * @return 返回签名算法名称。
 * @since 20
 */
const char *OH_CryptoSign_GetAlgoName(OH_CryptoSign *ctx);

/**
 * @brief 设置签名实例的指定参数。
 *
 * @param ctx 指向签名实例。
 * @param type 签名参数类型。
 * @param value 输入数据。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoSign_SetParam(OH_CryptoSign *ctx, CryptoSignature_ParamType type,
    const Crypto_DataBlob *value);

/**
 * @brief 从签名实例获取指定参数。
 *
 * @param ctx 指向签名实例。
 * @param type 签名参数类型。
 * @param value 输出数据。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoSign_GetParam(OH_CryptoSign *ctx, CryptoSignature_ParamType type, Crypto_DataBlob *value);

/**
 * @brief 销毁签名实例。
 *
 * @param ctx 指向签名实例。
 * @since 20
 */
void OH_CryptoSign_Destroy(OH_CryptoSign *ctx);

/**
 * @brief 定义ECC签名规范结构体。
 *
 * @since 20
 */
typedef struct OH_CryptoEccSignatureSpec OH_CryptoEccSignatureSpec;

/**
 * @brief 创建ECC签名规范。
 *
 * @param eccSignature ECC签名（DER格式），如果EccSignature参数为NULL，将创建一个空的ECC签名规范。
 * @param spec 输出的ECC签名规范。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoEccSignatureSpec_Create(Crypto_DataBlob *eccSignature,
    OH_CryptoEccSignatureSpec **spec);

/**
 * @brief 获取ECC签名的r和s值。
 *
 * @param spec 指向ECC签名规范。
 * @param r r值。
 * @param s s值。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoEccSignatureSpec_GetRAndS(OH_CryptoEccSignatureSpec *spec, Crypto_DataBlob *r,
    Crypto_DataBlob *s);

/**
 * @brief 设置ECC签名的r和s值。
 *
 * @param spec 指向ECC签名规范。
 * @param r r值。
 * @param s s值。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoEccSignatureSpec_SetRAndS(OH_CryptoEccSignatureSpec *spec, Crypto_DataBlob *r,
    Crypto_DataBlob *s);

/**
 * @brief 将ECC签名规范编码为DER格式的签名。
 *
 * @param spec 指向ECC签名规范。
 * @param out 输出数据。
 * @return CRYPTO_SUCCESS：操作成功。\n
 *         CRYPTO_NOT_SUPPORTED：操作不支持。\n
 *         CRYPTO_MEMORY_ERROR：内存错误。\n
 *         CRYPTO_PARAMETER_CHECK_FAILED：参数检查失败。\n
 *         CRYPTO_OPERATION_ERROR：调用三方算法库API出错。
 * @since 20
 */
OH_Crypto_ErrCode OH_CryptoEccSignatureSpec_Encode(OH_CryptoEccSignatureSpec *spec, Crypto_DataBlob *out);

/**
 * @brief 销毁ECC签名规范。
 *
 * @param spec 指向ECC签名规范。
 * @since 20
 */
void OH_CryptoEccSignatureSpec_Destroy(OH_CryptoEccSignatureSpec *spec);

#ifdef __cplusplus
}
#endif

/** @} */
#endif /* CRYPTO_SIGNATURE_H */
